using System;
using System.IO;
using System.Runtime.Serialization;
using System.Text;
using System.Xml;

namespace Xnatlas.Serialization
{
    public static class AtlasStoreSerializer
    {
        private static DataContractSerializer _serializer;

        public static AtlasStore LoadFromFile(string fileName, StorageType storageType)
        {
            switch (storageType)
            {
                case StorageType.Xml:
                    return LoadFromXmlFile(fileName + ".xml");
                case StorageType.Json:
                    return LoadFromJsonFile(fileName + ".json");
                default:
                    throw new ArgumentOutOfRangeException("storageType");
            }
        }

        public static void SaveToFile(AtlasStore atlasStore, string fileName, StorageType storageType)
        {
            switch (storageType)
            {
                case StorageType.Xml:
                    SaveToXmlFile(atlasStore, fileName + ".xml");
                    break;
                case StorageType.Json:
                    SaveToJsonFile(atlasStore, fileName + ".json");
                    break;
                default:
                    throw new ArgumentOutOfRangeException("storageType");
            }
        }

        public static AtlasStore LoadFromJsonFile(string fileName)
        {
            string json = File.ReadAllText(fileName, Encoding.UTF8);
            return SimpleJson.SimpleJson.DeserializeObject<AtlasStore>(json);
        }

        public static AtlasStore SaveToJsonFile(AtlasStore atlasStore, string fileName)
        {
            string json = SimpleJson.SimpleJson.SerializeObject(atlasStore);
            File.WriteAllText(fileName, json, Encoding.UTF8);
            return atlasStore;
        }

        public static AtlasStore LoadFromXmlFile(string fileName)
        {
            Stream stream = new FileStream(fileName, FileMode.Open);
            AtlasStore atlasStore = (AtlasStore)GetDataContractSerializer().ReadObject(stream);
            return atlasStore;
        }

        public static void SaveToXmlFile(AtlasStore atlasStore, string fileName)
        {
            XmlWriterSettings settings = new XmlWriterSettings { Indent = true };
            using (MemoryStream stream = new MemoryStream())
            using (XmlWriter xmlWriter = XmlWriter.Create(stream, settings))
            {
                GetDataContractSerializer().WriteObject(xmlWriter, atlasStore);
                xmlWriter.Flush();
                xmlWriter.Close();

                stream.Position = 0;
                byte[] buffer = stream.ToArray();
                File.WriteAllBytes(fileName, buffer);
            }
        }

        private static DataContractSerializer GetDataContractSerializer()
        {
            return _serializer ?? (_serializer = new DataContractSerializer(typeof(AtlasStore)));
        }
    }
}